iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0
Modern Web

Vue 演進驗證 × AI Coding 時代的工程實踐系列 第 16

Day 16:大量列表為什麼卡?

  • 分享至 

  • xImage
  •  
你相信嗎?大量 UI 本身,就可能成為 Runtime Cost

前幾天,我們一直在追 資料發生變化之後,Vue 到底需要做多少工作?

Reactive Chain Hell 看的是一次資料變更,Reactive Graph 會把更新傳到哪裡?

Component Storm 接著看一次更新,會影響多少 Component?

到了大量列表,問題開始換一個方向。

假設 API 一次拿回 5,000 筆商品,資料已經存在 JavaScript 裡,接下來的問題是 這 5,000 筆資料要變成畫面,瀏覽器需要做多少工作?

資料拿到了,畫面還是可能很慢


從 JavaScript 的角度來看,5,000 筆商品可能只是一個 Array:

API
 │
 ▼
5,000 items

但如果這些資料全部需要出現在畫面上,事情就會繼續往下發生:

5,000 items
     │
     ▼
建立 UI
     │
     ▼
大量 DOM
     │
     ▼
Style / Layout
     │
     ▼
Paint / Composite
     │
     ▼
畫面呈現

而且一個商品通常也不會只有一個 <div> ,可能還包含:

Product Card
├─ Image
├─ Title
├─ Price
├─ Badge
├─ Rating
└─ Button

因此真正需要處理的 UI 數量,往往會比 5,000 筆資料這個數字更大,這也是大型列表常見的問題 資料量增加之後,UI Workload 也跟著增加。

資料拿到了,畫面還是可能很慢

為什麼換更快的裝置,問題還可能存在?


裝置效能確實會影響執行時間,假設同樣需要處理 5,000 個 UI:

較慢裝置
5,000 UI
   ↓
需要較長時間完成

較快裝置
5,000 UI
   ↓
需要較短時間完成

更快的 CPU、GPU 或瀏覽器環境,可以讓這些工作更快完成,但是有一個問題仍然存在:

裝置變快
   ↓
單位工作時間下降

UI 數量不變
   ↓
總工作量仍然存在

所以當列表從 100 筆增加到 5,000 筆時,值得追蹤的問題就不只是「裝置夠不夠快」,還需要知道 UI 數量增加之後,究竟增加了哪些工作?

這時候不能直接拿真實電商網站來測


如果直接拿大型電商網站測試,很容易得到一個真的很慢的結果,但我們很難知道慢在哪裡,因為一個真實列表可能同時包含:

API / Network
      │
      ▼
State Management
      │
      ▼
Vue Reactivity
      │
      ▼
Component Tree
      │
      ▼
     DOM
      │
      ▼
CSS / Layout / Paint

最後看到一個 500ms 的結果時,還會有很多問題:

  • API 花了多少時間?
  • JavaScript 花了多少時間?
  • Vue Runtime 花了多少時間?
  • DOM 建立花了多少時間?
  • Browser Rendering 花了多少時間?
  • 圖片載入是否影響結果?

如果這些因素全部混在一起,就很難回答我們真正想研究的問題。

所以這次先把問題縮小


Day 16 想研究的事情其實只是 UI 數量持續增加,瀏覽器需要付出多少成本?

因此下一個 Scenario 會刻意移除與這個問題無關的因素:

                    VDOM Stress Test

                     UI 數量增加
                          │
                          ▼
                ┌─────────────────┐
                │  Vue 建立 UI    │
                └────────┬────────┘
                         │
                         ▼
                    大量 DOM
                         │
              ┌──────────┼──────────┐
              ▼          ▼          ▼
          Scripting   Rendering   Painting

這裡不需要 API、Pinia、Router,也不需要複雜的商業邏輯,只需要控制一個重要變數:

UI Count

100
 ↓
500
 ↓
1,000
 ↓
5,000

然後觀察成本如何隨著 UI 數量增加而變化。

Scenario 不需要模擬一個真實電商


因此 Scenario 本身會非常簡單,概念上只需要建立大量相同結構的 UI,商品內容不重要,真正重要的是 <div> 數量逐步增加,建立這些 UI 的成本如何變化?

<div
  v-for="item in items"
  :key="item.id"
  class="card"
>
  <h3>{{ item.title }}</h3>
  <p>{{ item.price }}</p>
  <button>Buy</button>
</div>

這也是為什麼這個 Scenario 叫做 VDOM Stress Test

它關注的不是 VDOM 本身的理論,而是當 Vue 需要處理大量 UI 時,整個 Rendering Workload 會發生什麼變化。

「慢」還需要繼續拆


如果最後只得到 5,000 個 UI 比 500 個 UI 慢,這個結果其實不夠有價值。

因為「慢」只是一個現象,我們還需要知道時間主要落在哪裡,所以可以先用 Browser Performance 的工作類型來理解:

Browser Work
│
├─ Scripting
│   └─ JavaScript / Vue Runtime
│
├─ Rendering
│   ├─ Style
│   └─ Layout
│
└─ Painting
    └─ Paint / Composite

因此後續驗證會關注幾個方向:

指標 想回答的問題
Execution / Duration 整體工作花多久?
Scripting JavaScript 與 Vue 相關工作增加多少?
Rendering Style / Layout 成本是否增加?
Painting Paint 成本是否增加?
FPS UI 增加後是否開始影響畫面更新?
Memory 大量 UI 是否帶來額外記憶體壓力?

這些指標的目的是運用 DevTools 數字回答一個核心問題:

大量 UI 帶來的成本,主要落在哪一層?

三個 Scenario,現在看的已經是不同問題


做到這裡,前面的三個 Scenario 可以放在同一張圖裡看。

                    Vue UI Performance

                           │
          ┌────────────────┼────────────────┐
          │                │                │
          ▼                ▼                ▼
   Reactive Chain     Component Storm   VDOM Stress
          │                │                │
          ▼                ▼                ▼
   更新傳播到哪裡?    影響多少 Component?   需要處理多少 UI?
          │                │                │
          ▼                ▼                ▼
   Reactive Graph      Component Tree      Rendering

它們可能在同一次操作中同時出現,但每個 Scenario 都刻意放大一個不同的維度:

Scenario 核心問題 主要觀察
Reactive Chain Hell 更新會傳到哪裡? Reactive Graph
Component Storm 更新會經過多少 Component? Component Tree
VDOM Stress Test UI 數量增加後會發生什麼? Rendering Workload

這樣看,大量列表的問題就會更清楚,當資料很多時,問題不一定停留在「資料有多少」。

資料一旦需要轉成大量 UI,就會進一步產生:

Data
 ↓
UI Instances
 ↓
DOM
 ↓
Browser Work

而我們真正需要驗證的,是這條路徑上的成本如何隨著 UI 數量增加。

下一步:建立 VDOM Stress Test


Day 16 先把問題縮小到「大量 UI」本身。

下一篇會正式建立 VDOM Stress Test,固定 Scenario 結構,只改變 UI 數量,從:

N = 100
N = 500
N = 1,000
N = 5,000

開始建立 baseline。

接著再比較不同 Vue 版本的結果。

這一次要回答的問題也很明確:

當 UI 數量從 100 增加到 5,000,成本增加在哪裡?Vue Runtime 又佔了多少?

等 baseline 跑完,才有資格進一步討論 Vue 3.6 是否真的改善了這類大量 UI 的成本。

參考資料



上一篇
Day 15:AI Coding 如何避免 Component Explosion?
下一篇
Day 17:建立 VDOM Stress Test Scenario
系列文
Vue 演進驗證 × AI Coding 時代的工程實踐23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言